package com.open.tools;

import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializer;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonDeserializationContext;
/**
 * 
 * @ClassName: JsonUtil    
 * @Description: TODO转换JSON工具类  
 * @author lism    
 * @date 2016年6月6日 上午11:39:37    
 *
 */
public class JsonUtil {

	private JsonUtil() {
	}

	private static Gson gson;

	/**
	 * 获取Gson的实例
	 * 
	 * @param createNew
	 *            方式：true,创建新实例；false 存在的gson实例。
	 * @return
	 */
	private static synchronized Gson getGsonInstance(Boolean createNew) {
		if (createNew) {
			return new Gson();
		} else if (gson == null) {
			gson = new Gson();
		}
		return gson;
	}

	// ========================================我是邪恶的分割线===============================================

	/**
	 * java对象转json字符窜1
	 * 
	 * @param obj
	 *            要被转换的java对象
	 * @return json字符窜
	 * @throws Exception
	 */
	public static String toJson(Object obj) throws Exception {
		try {
			Gson gson = getGsonInstance(false);
			return gson.toJson(obj);
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}
	}

	/**
	 * java对象转json字符窜2
	 * 
	 * @param obj
	 *            要被转换的java对象
	 * @param createNew
	 *            Gson实例方式:true，新实例;false,存在的gson实例
	 * @return json字符窜
	 * @throws Exception
	 */
	public static String toJson(Object obj, Boolean createNew) throws Exception {
		try {
			Gson gson = getGsonInstance(createNew);
			return gson.toJson(obj);
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}
	}

	// ========================================我是邪恶的分割线===============================================

	/**
	 * json字符窜转java对象1
	 * 
	 * @param jsonstr
	 *            准备转换的json字符串
	 * @param type
	 *            准备转换的类对象(e.g Student.class)
	 * @return 该类的java对象
	 * @throws Exception
	 */
	public static <T> T fromJson(String jsonstr, Type type) throws Exception {
		try {
			Gson gson = getGsonInstance(false);
			return gson.fromJson(jsonstr, type);
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}
	}

	/**
	 * json字符窜转java对象2
	 * 
	 * @param jsonstr
	 *            准备转换的json字符串
	 * @param type
	 *            准备转换的类对象(e.g Student.class)
	 * @param createNew
	 *            Gson实例方式:true，新实例;false,存在的gson实例
	 * @return 该类的java对象
	 * @throws Exception
	 */
	public static <T> T fromJson(String jsonstr, Type type, Boolean createNew)
			throws Exception {
		try {
			Gson gson = getGsonInstance(createNew);
			return gson.fromJson(jsonstr, type);
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}
	}

	// ========================================我是邪恶的分割线===============================================

	/**
	 * json字符窜转java对象(集合)1
	 * 
	 * @param jsonstr
	 *            准备转换的json字符串
	 * @param type
	 *            准备转换的类对象(e.g new TypeToken<List<Student>>() {}.getType())
	 * @return 该类的java对象(集合)
	 * @throws Exception
	 */
	public static <T> T fromJson(String jsonstr, Class<T> type)
			throws Exception {
		try {
			Gson gson = getGsonInstance(false);
			return gson.fromJson(jsonstr, type);
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}
	}

	/**
	 * json字符窜转java对象(集合)2
	 * 
	 * @param jsonstr
	 *            准备转换的json字符串
	 * @param type
	 *            准备转换的类对象(e.g new TypeToken<List<Student>>() {}.getType())
	 * @param createNew
	 *            Gson实例方式:true，新实例;false,存在的gson实例
	 * @return 该类的java对象(集合)
	 * @throws Exception
	 */
	public static <T> T fromJson(String jsonstr, Class<T> type,
			Boolean createNew) throws Exception {
		try {
			Gson gson = getGsonInstance(createNew);
			return gson.fromJson(jsonstr, type);
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}
	}
	
	/**
	 * 使用指定的json字符串，生成JsonElement。
	 * 支持json对象格式({xxx:xxx, yyy:yyy})、json数组格式([{xxx:xxx}, {yyy:yyy}])。
	 * @param jsonString
	 * @return
	 */
	public static JsonElement toJsonObject(String jsonString) {
		return new JsonParser().parse(jsonString);
	}
	

	/**
	 * 对象转换成JsonElement
	 * @param src
	 * @return
	 * @throws Exception
	 */
	public static JsonElement objToJson(Object src) throws Exception {
		Gson gson = getGsonInstance(false);
		return gson.toJsonTree(src);
	}
	
	/**
	 * 将Json对象用Java对象的方式表现出来
	 * @param element
	 * @return
	 */
	public static Object envelopJson(JsonElement element) {
		if (element.isJsonObject()) {
			LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
			Set<Entry<String, JsonElement>> entrySet = ((JsonObject) element).entrySet();
			for (Entry<String, JsonElement> entry: entrySet) {
				map.put(entry.getKey(), envelopJson(entry.getValue()));
			}
			return map;
		} else
		if (element.isJsonArray()) {
			ArrayList<Object> list = new ArrayList<Object>();
			Iterator<JsonElement> it = ((JsonArray) element).iterator();
			while (it.hasNext()) {
				JsonElement elChild = it.next();
				list.add(envelopJson(elChild));
			}
			return list;
		} else 
		if (element.isJsonPrimitive()){
			JsonPrimitive primitive = (JsonPrimitive) element;
			if (primitive.isBoolean()) {
				return element.getAsBoolean();
			}
			if (primitive.isNumber()) {
				return primitive.getAsNumber();
			} else 
				return primitive.getAsString();
		}
		return null;
	}

	/**
	 * 获取JsonObject指定名称的下级JsonObject
	 * @param src
	 * @param key
	 * @return
	 */
	public static JsonObject getObjectPropertyOf(JsonObject src, String key) {
		JsonElement el = src.get(key);
		if (el != null) {
			if (el.isJsonObject()) return el.getAsJsonObject();
		}
		return null;
	}

	/**
	 * 获取JsonObject指定名称的字符串属性值
	 * @param src
	 * @param key
	 * @return
	 */
	public static String getStringPropertyOf(JsonObject src, String key) {
		JsonElement el = src.get(key);
		if (el != null && !el.isJsonNull()) { 
			return el.getAsString();
		}
		return null;
	}

	/**
	 * 获取JsonObject指定名称的下级JsonArray
	 * @param src
	 * @param key
	 * @return
	 */
	public static JsonArray getJsonArrayPropertyOf(JsonObject src, String key) {
		JsonElement el = src.get(key);
		if (el != null) {
			if (el.isJsonArray()) return el.getAsJsonArray();
		}
		return null;
	}

	@SuppressWarnings("unchecked")
	public static Map<String, Object> toMap(JsonObject src) {
		return (Map<String, Object>) envelopJson(src);  
	}
	 /**
     * 将对象转换成json格式(并自定义日期格式)
     * @param ts
     * @return
     */
    public static String objectToJsonDateSerializer(Object ts,final String dateformat){
        String jsonStr=null;
        gson=new GsonBuilder().registerTypeAdapter(Date.class, new JsonSerializer<Date>() {
            public JsonElement serialize(Date src, Type typeOfSrc,
                    JsonSerializationContext context) {
                SimpleDateFormat format = new SimpleDateFormat(dateformat);
                return new JsonPrimitive(format.format(src));
            }
        }).setDateFormat(dateformat).create();
        if(gson!=null){
            jsonStr=gson.toJson(ts);
        }
        return jsonStr;
    }
    
    /**
     * 将json转换成bean对象
     * @param jsonStr
     * @return
     */
    @SuppressWarnings("unchecked")
	public static <T> T  jsonToBean(String jsonStr,Class<T> cl){
        Object obj=null;
        Gson gson = getGsonInstance(false);
        if(gson!=null){
            obj=gson.fromJson(jsonStr, cl);
        }
        return (T) obj;
    }
    /**
     * 将json转换成bean对象
     * @param jsonStr
     * @param cl
     * @param pattern 时间格式
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> T  jsonToBeanDateSerializer(String jsonStr,Class<T> cl,final String pattern){
        Object obj=null;
        gson=new GsonBuilder().registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
            public Date deserialize(JsonElement json, Type typeOfT,
                    JsonDeserializationContext context)
                    throws JsonParseException {
                    SimpleDateFormat format=new SimpleDateFormat(pattern);
                    String dateStr=json.getAsString();
                try {
                    return format.parse(dateStr);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                return null;
            }
        }).setDateFormat(pattern).create();
        if(gson!=null){
            obj=gson.fromJson(jsonStr, cl);
        }
        return (T)obj;
    }
    /**
     * 
     * @Title: jsonToBeanList 
     * @Description: TODO json转对象集合
     * @param json
     * @param c
     * @return
     * @throws Exception     
     * @return List<T>     
     * @throws
     *
     * @date 2016年6月16日 下午4:26:26
     * @author lism
     */
    public static <T> List<T> jsonToBeanList(String json,Class<T> c) throws Exception{
    	JsonElement jo = toJsonObject(json);
    	List<T> list = new ArrayList<T>();
    	if(jo.isJsonArray()){
    		JsonArray joArr = jo.getAsJsonArray();
    		for(int i=0;i<joArr.size();i++){
    			list.add(jsonToBean(joArr.get(i).toString(), c));
    		}
    	}
    	return list;
    	
    }
}
